﻿using Bzw.Data;
using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Text;
using System.Web.Mvc;
using System.Web.Security;
using System.Xml;
using HuntingFishGame.Domain.BLL.WeChat;

namespace HuntingFishGame.CustomerApi.Controllers
{
    public class WeiXinAPIController : Controller
    {
        string Token = "lydgame";
        // GET: WeiXinAPI
        public void Index()
        {
            //设置token值
            //string strtoken = Helper.GetConfig("token");
            string strtoken = WeixinConfig.BaseAccessToken(WeixinType.CertServiceAccount).ParamValue;
            if (!string.IsNullOrEmpty(strtoken))
                Token = strtoken;

            //2.微信服务器post请求
            string postStr = "";
            if (Request.HttpMethod.ToLower() == "post")
            {
                //微信发送的请求
                postStr = PostInput();
                if (!string.IsNullOrEmpty(postStr))
                {
                    ResponseMsg(postStr);//根据微信发送的信息，进行不同的操作
                }
            }
            else
            {
                //1.微信第一次验证url，的get请求
                Valid();
            }
        }

        #region 获取微信服务器返回客户传给我方平台的post数据
        /// <summary>
        /// 获取微信服务器返回客户传给我方平台的post数据
        /// </summary>
        /// <returns></returns>
        private string PostInput()
        {
            Stream s = System.Web.HttpContext.Current.Request.InputStream;
            byte[] b = new byte[s.Length];
            s.Read(b, 0, (int)s.Length);
            return Encoding.UTF8.GetString(b);
        }
        #endregion

        #region 根据微信发送的信息，进行不同的操作
        /// <summary>
        ///返回微信信息结果
        /// </summary>
        /// <param name="weixinXML"></param>
        private void ResponseMsg(string weixin)// 服务器响应微信请求
        {
            XmlDocument doc = new XmlDocument();
            doc.LoadXml(weixin);//读取xml字符串
            XmlElement root = doc.DocumentElement;
            ExmlMsg xmlMsg = GetExmlMsg(root);
            string messageType = xmlMsg.MsgType;//获取收到的消息类型。文本(text)，图片(image)，语音等。
            try
            {
                switch (messageType)
                {
                    //当消息为文本时
                    case "text":
                        Helper.ExtLog("someone guanzhu our mp");
                        //刚关注时的时间，用于欢迎词  
                        int nowtime1 = ConvertDateTimeInt(DateTime.Now);
                        string resxml1 = "<xml><ToUserName><![CDATA[" + xmlMsg.FromUserName + "]]></ToUserName><FromUserName><![CDATA[" + xmlMsg.ToUserName + "]]></FromUserName><CreateTime>"
                                      + nowtime1 + "</CreateTime><MsgType><![CDATA[transfer_customer_service]]></MsgType></xml>";
                        Response.Write(resxml1);
                        break;
                    case "event":
                        Helper.ExtLog("someone trigger a event");
                        if (!string.IsNullOrEmpty(xmlMsg.EventName) && xmlMsg.EventName.Trim() == "subscribe")//subscribe订阅 unsubscribe取消订阅
                        {
                            if (!string.IsNullOrEmpty(xmlMsg.EventKey) && xmlMsg.EventKey.Contains("qrscene_"))
                            {
                                eventCase(xmlMsg);
                            }
                            else
                            {
                                //刚关注时的时候，用于欢迎词  
                                string resxml = textCase(xmlMsg);
                                Response.Write(resxml);
                            }
                        }
                        else if (!string.IsNullOrEmpty(xmlMsg.EventName) && xmlMsg.EventName.Trim() == "SCAN")
                        {
                            eventCase(xmlMsg);
                        }
                        break;
                    case "image":
                        break;
                    case "voice":
                        break;
                    case "vedio":
                        break;
                    case "location":
                        break;
                    case "link":
                        break;
                    default:
                        break;
                }
                Response.End();
            }
            catch (Exception)
            { }
        }
        #endregion

        #region 操作文本消息 + void eventCase(XmlElement root)
        /// <summary>
        /// 操作文本消息
        /// </summary>
        /// <param name="xmlMsg"></param>
        private void eventCase(ExmlMsg xmlMsg)
        {
            string returnValue = "接收到EventKey：" + xmlMsg.EventKey + ". ";//存储过程的返回值
            int nowtime = ConvertDateTimeInt(DateTime.Now);
            string msg = "";//返回给微信的值
            string keyContent = "";
            if (!string.IsNullOrEmpty(xmlMsg.EventKey))//判断事件的key值 例如:key值为qrscene_9955,888888或者9955,888888
            {
                string[] keyContents = xmlMsg.EventKey.Split(',');
                if (keyContents.Length == 2)
                {
                    //获取得到9955【用户编码】
                    if (keyContents[0].Contains("qrscene_"))
                    {
                        keyContent = keyContents[0].Split('_')[1];
                    }
                    else
                    {
                        keyContent = keyContents[0];
                    }

                    //第二个参数【验证码】不为空
                    if (!string.IsNullOrEmpty(keyContent) && !string.IsNullOrEmpty(keyContents[1]))
                    {
                        if (keyContent.Length >= 4 && keyContents[1].Length == 6)
                        {
                            try
                            {
                                int userid = int.Parse(keyContent);//用户ID
                                int code = int.Parse(keyContents[1]);//验证码

                                Dictionary<string, object> dic = new Dictionary<string, object>();
                                //执行存储过程【用户绑定微信发送验证码】
                                DbSession.Default.FromProc("SP_UserBindWxCode")
                                .AddInputParameter("@UserID", DbType.String, userid)
                                .AddInputParameter("@WxCode", DbType.String, xmlMsg.FromUserName)
                                .AddInputParameter("@ChkCode", DbType.String, code)
                                .AddReturnValueParameter("@Return_Value", DbType.Int32)
                                .Execute(out dic);

                                Helper.ExtLog("传入存储过程参数：userid=" + userid + ";wxcode=" + xmlMsg.FromUserName + ";chkcode=" + code);

                                if (dic.Count > 0)
                                {
                                    string result = dic["Return_Value"].ToString();//得到执行结果

                                    Helper.ExtLog("存储过程返回结果：" + result);

                                    if (result == "0")
                                    {
                                        msg = "您的微信已成功绑定猎鱼岛游戏账号，游戏账号ID：" + userid + "！";
                                        returnValue += msg;
                                    }
                                    else if (result == "1")
                                    {
                                        msg = "绑定用户失败，验证码输入有误，请重新输入。";
                                        returnValue += "用户ID不能为空";
                                    }
                                    else if (result == "2")
                                    {
                                        msg = "绑定用户失败，验证码输入有误，请重新输入。";
                                        returnValue += "微信号不能为空";
                                    }
                                    else if (result == "3")
                                    {
                                        msg = "绑定用户失败，验证码输入有误，请重新输入。";
                                        returnValue += "请确认你的游戏ID是否正确";
                                    }
                                    else if (result == "4")
                                    {
                                        msg = "绑定用户失败，请获取验证码。";
                                        returnValue += "请重新获取验证码";
                                    }
                                    else if (result == "5")
                                    {
                                        msg = "绑定用户失败，你已经绑定微信号，不能重复绑定。";
                                        returnValue += "你已经绑定微信号，不能重复绑定";
                                    }
                                    else if (result == "6")
                                    {
                                        msg = "绑定用户失败，验证码错误。";
                                        returnValue += "验证码错误";
                                    }
                                    else if (result == "7")
                                    {
                                        msg = "绑定用户失败，验证码过期,请在游戏客户端重新获取。";
                                        returnValue += "验证码过期";
                                    }
                                }
                            }
                            catch (Exception e)
                            {
                                returnValue += "出现异常" + e.ToString();
                                msg = "绑定用户失败，验证码输入有误，请重新输入。";
                            }
                        }
                        else
                        {
                            returnValue += "UserID和code长度不够。";
                            msg = "绑定用户失败，验证码输入有误，请重新输入。";
                        }
                    }
                    else
                    {
                        returnValue += "UserID和code为空！";
                        msg = "绑定用户失败，验证码输入有误，请重新输入。";
                    }
                }
                ///日志
                LogClass log = new LogClass();
                string url = "log\\" + DateTime.Now.ToString("yyyy-MM-dd") + "log.txt";
                string logContent = "用户绑定微信号结果为：" + returnValue + ",时间为：" + DateTime.Now;
                log.WriteLog(logContent, Server.MapPath(url));

                string resxml = "<xml><ToUserName><![CDATA[" + xmlMsg.FromUserName + "]]></ToUserName><FromUserName><![CDATA[" + xmlMsg.ToUserName + "]]></FromUserName><CreateTime>" + nowtime
                         + "</CreateTime><MsgType><![CDATA[text]]></MsgType><Content><![CDATA[" + msg + "]]></Content><FuncFlag>0</FuncFlag></xml>";
                Response.Write(resxml);
            }
        }
        #endregion

        #region 将datetime.now 转换为 int类型的秒
        /// <summary>
        /// datetime转换为unixtime
        /// </summary>
        /// <param name="time"></param>
        /// <returns></returns>
        private int ConvertDateTimeInt(System.DateTime time)
        {
            System.DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1));
            return (int)(time - startTime).TotalSeconds;
        }
        private int converDateTimeInt(System.DateTime time)
        {
            System.DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1));
            return (int)(time - startTime).TotalSeconds;
        }

        /// <summary>
        /// unix时间转换为datetime
        /// </summary>
        /// <param name="timeStamp"></param>
        /// <returns></returns>
        private DateTime UnixTimeToTime(string timeStamp)
        {
            DateTime dtStart = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1));
            long lTime = long.Parse(timeStamp + "0000000");
            TimeSpan toNow = new TimeSpan(lTime);
            return dtStart.Add(toNow);
        }
        #endregion

        #region 验证微信签名 保持默认即可
        /// <summary>
        /// 第一次验证url有效性，微信发起GET请求
        /// </summary>
        private void Valid()
        {
            //获取微信发送给服务器的随机字符串
            string echoStr = Request.QueryString["echoStr"].ToString();
            //判断签名通过，向微信服务器原样返回随机字符串
            if (CheckSignature())
            {
                if (!string.IsNullOrEmpty(echoStr))
                {
                    Response.Write(echoStr);
                    Response.End();
                }
            }
        }

        /// <summary>
        /// 验证微信签名
        /// </summary>
        /// * 将token、timestamp、nonce三个参数进行字典序排序
        /// * 将三个参数字符串拼接成一个字符串进行sha1加密
        /// * 开发者获得加密后的字符串可与signature对比，标识该请求来源于微信。
        /// <returns></returns>
        private bool CheckSignature()
        {
            string signature = Request.QueryString["signature"].ToString();//微信加密签名
            string timestamp = Request.QueryString["timestamp"].ToString();//时间戳
            string nonce = Request.QueryString["nonce"].ToString();//随机数
            string[] ArrTmp = { Token, timestamp, nonce };
            Array.Sort(ArrTmp);     //字典排序
            string tmpStr = string.Join("", ArrTmp);
            tmpStr = FormsAuthentication.HashPasswordForStoringInConfigFile(tmpStr, "SHA1");//加密
            tmpStr = tmpStr.ToLower();

            //与微信加密判断，一致返回真
            if (tmpStr == signature)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        #endregion

        #region 接收的消息实体类 以及 填充方法
        /// <summary>
        /// 接收的消息实体类 以及 填充方法
        /// </summary>
        private class ExmlMsg
        {
            /// <summary>
            /// 接收微信号
            /// </summary>
            public string ToUserName
            {
                get;
                set;
            }
            /// <summary>
            /// 发送微信好
            /// </summary>
            public string FromUserName
            {
                get;
                set;
            }
            /// <summary>
            /// 发送时间戳
            /// </summary>
            public string CreateTime
            {
                get;
                set;
            }
            /// <summary>
            /// 发送的文本内容
            /// </summary>
            public string Content
            {
                get;
                set;
            }
            /// <summary>
            /// 消息的类型
            /// </summary>
            public string MsgType
            {
                get;
                set;
            }
            /// <summary>
            /// 事件名称
            /// </summary>
            public string EventName
            {
                get;
                set;
            }
            /// <summary>
            /// 事件参数
            /// </summary>
            public string EventKey
            {
                get;
                set;
            }
        }
        /// <summary>
        /// 接收用户发送的消息
        /// </summary>
        /// <param name="root"></param>
        /// <returns></returns>
        private ExmlMsg GetExmlMsg(XmlElement root)
        {
            LogClass log = new LogClass();
            string logContent = "接受到的：" + root.InnerXml + ",时间为：" + DateTime.Now;
            string url3 = "log\\" + DateTime.Now.ToString("yyyy-MM-dd") + "log.txt";
            log.WriteLog(logContent, Server.MapPath(url3));

            ExmlMsg xmlMsg = new ExmlMsg()
            {
                FromUserName = root.SelectSingleNode("FromUserName").InnerText,
                ToUserName = root.SelectSingleNode("ToUserName").InnerText,
                CreateTime = root.SelectSingleNode("CreateTime").InnerText,
                MsgType = root.SelectSingleNode("MsgType").InnerText,
            };
            if (xmlMsg.MsgType.Trim().ToLower() == "text")
            {
                xmlMsg.Content = root.SelectSingleNode("Content").InnerText;
            }
            else if (xmlMsg.MsgType.Trim().ToLower() == "event")
            {
                xmlMsg.EventName = root.SelectSingleNode("Event").InnerText;
                xmlMsg.EventKey = root.SelectSingleNode("EventKey").InnerText;
            }
            return xmlMsg;
        }
        #endregion

        #region 关注微信
        /// <summary>
        /// 关注微信
        /// </summary>
        /// <param name="xmlMsg"></param>
        private string textCase(ExmlMsg xmlMsg)
        {
            //刚关注时的时间，用于欢迎词  
            int nowtime = ConvertDateTimeInt(DateTime.Now);
            XmlDocument doc2 = new XmlDocument();
            string url = Server.MapPath("~/Config/About.config");
            doc2.Load(url);
            XmlNode dataNode = doc2.SelectSingleNode("data");
            XmlNode GreetingNode = dataNode.SelectSingleNode("Greeting");
            XmlElement xe = (XmlElement)GreetingNode;
            string GreetingValue = xe.GetAttribute("value").ToString();
            string resxml = "<xml><ToUserName><![CDATA[" + xmlMsg.FromUserName + "]]></ToUserName><FromUserName><![CDATA[" + xmlMsg.ToUserName + "]]></FromUserName><CreateTime>"
                          + nowtime + "</CreateTime><MsgType><![CDATA[text]]></MsgType><Content><![CDATA[" + GreetingValue + "]]></Content><FuncFlag>0</FuncFlag></xml>";
            return resxml;
        }
        #endregion
    }
}